package com.motorola.dp.jenkinsmonitor.service.util.dom;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.motorola.dp.jenkinsmonitor.model.util.dom.DomEntity;
import com.motorola.dp.jenkinsmonitor.service.util.ClassService;
import com.motorola.dp.jenkinsmonitor.service.util.dom.xpath.XpathExpressionCache;

@SuppressWarnings({ "rawtypes", "unchecked" })
@Component("domAnnotationProcessorHelper")
public class DomAnnotationProcessorHelper {

    @Value("#{classService}")
    private ClassService classService;

    @Value("#{xpathExpressionCache}")
    private XpathExpressionCache xpathExpressionCache;

    public String getDomEntityName(Class c) {
        DomEntity entityAnnotation = (DomEntity) c.getAnnotation(DomEntity.class);

        String entityName = entityAnnotation.name();
        if (DomEntity.NAME_UNSPECIFIED.equalsIgnoreCase(entityName)) {
            entityName = c.getSimpleName();
        }
        return entityName;
    }

    public void applyFieldValue(Object instance, Field field, Object value) throws Exception {
        Method setterMethod = classService.getSetterMethod(field, instance.getClass());
        setterMethod.invoke(instance, value);
    }

    public NodeList findNodesByXpath(Element parent, String expression) throws Exception {
        XPathExpression expr = xpathExpressionCache.lookup(expression);
        Object result = expr.evaluate(parent, XPathConstants.NODESET);
        return (NodeList) result;
    }

    public void setClassService(ClassService classService) {
        this.classService = classService;
    }

    public void setXpathExpressionCache(XpathExpressionCache xpathExpressionCache) {
        this.xpathExpressionCache = xpathExpressionCache;
    }
}
